﻿// ***********************************************************************
// Provided for Informational Purposes Only
//
// Apache 2.0 License
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
// ***********************************************************************
// Assembly  : ContractMeow.ModernApp
// File      : App.xaml.cs
//
// ***********************************************************************
using Caliburn.Micro;
using ContractMeow.Api;
using ContractMeow.Api.Clients;
using ContractMeow.Data.WinRT;
using ContractMeow.Data.WinRT.Api;
using ContractMeow.ModernApp.Views;
using ContractMeow.WinRT.Extensions;
using ContractMeow.WinRT.Serialization;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Net;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml.Controls;

// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227

namespace ContractMeow.ModernApp
{
	/// <summary>
	/// Provides application-specific behavior to supplement the default Application class.
	/// </summary>
	sealed partial class App : CaliburnApplication
	{
		private IUnityContainer _container;

		#region
		/* This should be stored in a secure location. 
		 * It is only here to simply demo purposes 
		 */
		private const String ApiClientId = "{Replace with actual Client Id}";
		private const String ApiClientSecret = "{Replace with actual Client Secret";
		#endregion


		/// <summary>
		/// Initializes the singleton application object.  This is the first line of authored code
		/// executed, and as such is the logical equivalent of main() or WinMain().
		/// </summary>
		public App()
		{
			this.InitializeComponent();
			this.Suspending += OnSuspending;
		}

		/// <summary>
		/// Invoked when the application is launched normally by the end user.  Other entry points
		/// will be used when the application is launched to open a specific file, to display
		/// search results, and so forth.
		/// </summary>
		/// <param name="args">Details about the launch request and process.</param>
		protected override void OnLaunched(LaunchActivatedEventArgs args)
		{
			DisplayRootView<LoginView>();
		}

		/// <summary>
		/// Invoked when application execution is being suspended.  Application state is saved
		/// without knowing whether the application will be terminated or resumed with the contents
		/// of memory still intact.
		/// </summary>
		/// <param name="sender">The source of the suspend request.</param>
		/// <param name="e">Details about the suspend request.</param>
		private void OnSuspending(object sender, SuspendingEventArgs e)
		{
			var deferral = e.SuspendingOperation.GetDeferral();
			//TODO: Save application state and stop any background activity
			deferral.Complete();
		}

		/// <summary>
		/// Override this to provide an IoC specific implementation.
		/// </summary>
		/// <param name="service">The service to locate.</param>
		/// <param name="key">The key to locate.</param>
		/// <returns>The located service.</returns>
		protected override Object GetInstance(Type service, String key)
		{
			return _container.Resolve(service, key);
		}

		/// <summary>
		/// Override this to provide an IoC specific implementation
		/// </summary>
		/// <param name="service">The service to locate.</param>
		/// <returns>The located services.</returns>
		protected override IEnumerable<Object> GetAllInstances(Type service)
		{
			return _container.ResolveAll(service);
		}

		/// <summary>
		/// Override this to provide an IoC specific implementation.
		/// </summary>
		/// <param name="instance">The instance to perform injection on.</param>
		protected override void BuildUp(Object instance)
		{
			_container.BuildUp(instance);
		}

		/// <summary>
		/// Prepares the view first.
		/// </summary>
		/// <param name="rootFrame">The root frame.</param>
		protected override void PrepareViewFirst(Frame rootFrame)
		{

			_container.RegisterInstance<INavigationService>(new FrameAdapter(RootFrame, false),
															new ContainerControlledLifetimeManager());
		}

		protected override void Configure()
		{
			base.Configure();

			_configureIoc();

		}

		private void _configureIoc()
		{
			_container = new UnityContainer();

			_container
				.RegisterSingletonType<IQueryStringSerializer, QueryStringSerializer>()
				.RegisterInstance<ISerializer>(new JsonDotNetSerializer())
				.RegisterInstance<IDeserializer>(new JsonDotNetDeserializer())
				.RegisterInstance<IWebProxy>(WebRequest.DefaultWebProxy)
				.RegisterSingletonType<ICookieStore, CookieStore>();

			_container
				.RegisterInstance<IClientConfiguration>(new ClientConfiguration(
															clientId: ApiClientId,
															clientSecret: ApiClientSecret))
				.RegisterSingletonType<IAuthClient, AuthClient>(
					new InjectionConstructor(typeof(IClientConfiguration),
											 typeof(IQueryStringSerializer),
											 typeof(ISerializer),
											 typeof(IDeserializer),
											 _container.Resolve<OAuthResponseErrorHandler>(),
											 typeof(ICookieStore),
											 typeof(IWebProxy)))
				.RegisterSingletonType<IAutoCompleteClient, AutoCompleteClient>(
					new InjectionConstructor(typeof(IClientConfiguration),
											 typeof(IQueryStringSerializer),
											 typeof(ISerializer),
											 typeof(IDeserializer),
											 _container.Resolve<OAuthResponseErrorHandler>(),
											 typeof(ICookieStore),
											 typeof(IWebProxy)))
				.RegisterSingletonType<IOpenGraphClient, OpenGraphClient>(
					new InjectionConstructor(typeof(IClientConfiguration),
											 typeof(IQueryStringSerializer),
											 typeof(ISerializer),
											 typeof(IDeserializer),
											 _container.Resolve<OAuthResponseErrorHandler>(),
											 typeof(ICookieStore),
											 typeof(IWebProxy)))
				.RegisterSingletonType<IUserClient, UserClient>(
					new InjectionConstructor(typeof(IClientConfiguration),
											 typeof(IQueryStringSerializer),
											 typeof(ISerializer),
											 typeof(IDeserializer),
											 _container.Resolve<OAuthResponseErrorHandler>(),
											 typeof(ICookieStore),
											 typeof(IWebProxy)))
				.RegisterSingletonType<IMessageClient, MessageClient>(
					new InjectionConstructor(typeof(IClientConfiguration),
											 typeof(IQueryStringSerializer),
											 typeof(ISerializer),
											 typeof(IDeserializer),
											 _container.Resolve<OAuthResponseErrorHandler>(),
											 typeof(ICookieStore),
											 typeof(IWebProxy)));


			_container
				.RegisterSingletonType<IStateManager, StateManager>()
				.RegisterSingletonType<IAuthRepository, AuthRepository>()
				.RegisterSingletonType<IUsersRepository, UsersRepository>()
				.RegisterSingletonType<IOpenGraphRepository, OpenGraphRepository>()
				.RegisterSingletonType<IUserRepository, UserRepository>()
				.RegisterSingletonType<IMessageRepository, MessageRepository>();
		}

	}
}
